<template>
  <div class="validate-input-container pb-3">
      <input
         class="form-control"
         :class="{ 'is-invalid' : inputRef.error }"
         :value="inputRef.val"
         @blur="validateInput"
         @input="undateValue"
         v-bind="$attrs"
      >
      <span v-if="inputRef.error" class="invalid-feedback">{{ inputRef.message }}</span>
  </div>
</template>

<script lang="ts">
import {defineComponent, reactive, PropType} from 'vue'

const emailReg = /^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/

interface RuleProp {
    type: 'required' | 'email'
    message: string
}
export type RulesProp = RuleProp[]
export default defineComponent({
    props:{
        rules: Array as PropType<RulesProp>,
        modelValue: String
    },
    inheritAttrs: false,
    setup(props, context) {
        const inputRef = reactive({
            val:props.modelValue || '',
            error:false,
            message:''
        })
        const undateValue = (e:KeyboardEvent) => {
            const targetValue = (e.target as HTMLInputElement).value
            inputRef.val = targetValue
            context.emit('update:modelValue', targetValue)
        }
        const validateInput = () => {
            if(props.rules) {
                const allPassed = props.rules.every(rule=>{
                    let passed = true
                    inputRef.message = rule.message
                    switch (rule.type) {
                        case 'required':
                            passed = (inputRef.val.trim() !== '')
                            break
                        case 'email':
                            passed = emailReg.test(inputRef.val)
                            break
                        default:
                            break
                    }
                    return passed
                })
                inputRef.error = !allPassed
                return allPassed
            }
            return true
        }
        return {
            inputRef,
            validateInput,
            undateValue
        }
    }
})
</script>

<style>

</style>